package com.zq.product.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zq.product.config.ExcelListener;
import com.zq.product.dao.entity.Category;
import com.zq.product.dao.vo.CategoryExcelVo;
import com.zq.product.mapper.CategoryMapper;
import com.zq.product.service.ICategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 商品分类 服务实现类
 * </p>
 *
 * @author 张乔
 * @since 2025-05-13
 */
@Service
@Slf4j
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {



//    获取所有的一级分类
    @Override
    @Cacheable(value ="category", key = "'ones'")
    public List<Category> ones() {
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Category::getParentId,0)
                .eq(Category::getStatus,1)
                .orderByAsc(Category::getOrderNum);

        List<Category> categories = this.list(wrapper);

        return categories;
    }

    //根据父级id获取子类
    @Override
    public List<Category> findByParentId(Long parentId) {
        // 根据分类id查询它下面的所有的子分类数据
        List<Category> categoryList = this.list(new LambdaQueryWrapper<Category>().
                eq(Category::getParentId,parentId));
        // 判断是否为空
        if(!CollectionUtils.isEmpty(categoryList)) {

            // 遍历分类的集合，获取每一个分类数据
            categoryList.forEach(item -> {

                // 查询该分类下子分类的数量
                int count = (int) this.count(new LambdaQueryWrapper<Category>()
                        .eq(Category::getParentId,item.getId()).
                        orderByAsc(Category::getId));
                item.setHasChildren(count > 0);

            });
        }
        return categoryList;
    }
@Resource
private RedisTemplate<String,String> redisTemplate;


    //导出
    @Override
    public void exportData(HttpServletResponse response) {
//        //1、设置响应头和其他信息
////设置响应的 MIME 类型为 "application/vnd.ms-excel"，表示响应内容为 Excel 文件。
//        httpServletResponse.setContentType("application/vnd.ms-excel");
////设置响应的字符编码为 UTF-8，以确保中文等特殊字符能正确显示。
//        httpServletResponse.setCharacterEncoding("utf-8");
////   这里的URLEncoder.encode()可以防止中文乱码，（这里有异常，直接抛出）
//        String fileName = null;
//        try {
//            fileName = URLEncoder.encode("分类数据","UTF-8");
//            //     设置响应头信息Content-disposition(这表示以下载方式打开文件),它告诉客户端浏览器以
////下载方式处理响应内容，并指定下载的文件名为 "分类数据.xlsx"（通过拼接上文件名和扩展名）
//            httpServletResponse.setHeader("Content-disposition", "attachment;filename="+fileName+".xlsx");
////2、调用mapper接口查询数据库中所有数据，返回list集合
//            String redisCategory = redisTemplate.opsForValue().get("category");
//            List<Category> categoryList=new ArrayList<>();
//
//            if(StringUtils.hasText(redisCategory)) {
//                categoryList = JSON.parseArray(redisCategory, Category.class);
//            }else {
//            categoryList=  this.list();
//            redisTemplate.opsForValue().set("category",
//                    JSON.toJSONString(categoryList),60, TimeUnit.MINUTES);
//            }
//
//            List<CategoryExcelVo> categoryExcelVos = new ArrayList<>();
//            categoryList.forEach(item -> {
//                CategoryExcelVo categoryExcelVo = new CategoryExcelVo();
//                BeanUtils.copyProperties(item,categoryExcelVo);
//            categoryExcelVos.add(categoryExcelVo);
//
//            });
////3、调用EasyExcel的wired方法完成写操作
//            EasyExcel.write(httpServletResponse.getOutputStream(),
//                    CategoryExcelVo.class).sheet("分类数据").
//                    doWrite(categoryExcelVos);
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
        try {

            // 设置响应结果类型
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");

            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("分类数据", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            //response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

            // 查询数据库中的数据
            List<Category> categoryList = this.list();
            List<CategoryExcelVo> categoryExcelVoList = new ArrayList<>(categoryList.size());

            // 将从数据库中查询到的Category对象转换成CategoryExcelVo对象
            for(Category category : categoryList) {
                CategoryExcelVo categoryExcelVo = new CategoryExcelVo();
                BeanUtils.copyProperties(category, categoryExcelVo, CategoryExcelVo.class);
                categoryExcelVoList.add(categoryExcelVo);
            }
            // 写出数据到浏览器端
            EasyExcel.write(response.getOutputStream(), CategoryExcelVo.class).sheet("分类数据").doWrite(categoryExcelVoList);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }


    @Resource
    private ExcelListener<CategoryExcelVo> easyExcelConfig;



    //    导入
    @Override
    public void importData(MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream(),CategoryExcelVo.class,easyExcelConfig)
                    .sheet()  //excel中表的名称，默认为第一个sheet
                    .doRead();
            List<CategoryExcelVo> categoryExcelVos = easyExcelConfig.getDatas();
//        将读取到的数据存入数据库中

           categoryExcelVos.forEach(item -> {
               Category category = new Category();
               BeanUtils.copyProperties(item,category);
               this.save(category);
           });


        } catch (IOException e) {
            throw new RuntimeException(e);
        }




    }


}
